Skip to content

[v24.x backport] buffer: fix Blob.stream() leaking source buffer - #64664

Open
gabrielbryk wants to merge 241 commits into
nodejs:v24.x-stagingfrom
gabrielbryk:backport-63577-to-v24.x
Open

[v24.x backport] buffer: fix Blob.stream() leaking source buffer#64664
gabrielbryk wants to merge 241 commits into
nodejs:v24.x-stagingfrom
gabrielbryk:backport-63577-to-v24.x

Conversation

@gabrielbryk

Copy link
Copy Markdown

Backport of #63577 to v24.x. It doesn't cherry-pick cleanly on its own: the
JS fix clears the reader's wakeup handle with reader.setWakeup(undefined),
but on v24.x the C++ Blob::Reader::SetWakeup still asserts a function
argument. The guard that makes it accept undefined only landed as part of
the QUIC commit cf91d18 (#62876), which isn't on this line, so a plain
cherry-pick builds but aborts the first time a stream reaches a terminal/idle
path:

Assertion failed: args[0]->IsFunction()
node::Blob::Reader::SetWakeup at src/node_blob.cc

The second commit extracts only that four-line node_blob.cc guard from
#62876; the rest of that commit (the NotifyPull(fin) / pull_pending_
coalescing) is QUIC-specific and not needed here. It could instead be done as
a prerequisite backport of #62876, or folded into the cherry-pick, if a
reviewer prefers.

parallel/test-blob*, including the new test-blob-stream-gc.js from #63577,
passes on a local build; the #63574 reproducer holds arrayBuffers flat where
24.16.0 leaks the source buffer on every stream.

panva and others added 30 commits June 25, 2026 15:30
Replace the O(n) case-insensitive algorithm-name scan
with an O(1) SafeMap lookup. The map is pre-built at
module init alongside kSupportedAlgorithms.

Hoist the opts object literal used in normalizeAlgorithm
to module level to avoid allocating identical
{ prefix, context } objects on every call.

Pre-compute ObjectKeys() for simpleAlgorithmDictionaries
entries at module init to avoid allocating a new keys
array on every normalizeAlgorithm call.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62756
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Replace object spread in nested WebIDL conversion
options with stable-shape ordinary objects. This keeps
hot dictionary and sequence conversion paths from
allocating null-prototype spread results.

Apply the same pattern to Web Crypto converter wrappers
that override allowResizable or enable [EnforceRange].

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62756
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Signed-off-by: Matteo Collina <matteo.collina@gmail.com>
PR-URL: nodejs#62562
Reviewed-By: James M Snell <jasnell@gmail.com>
Signed-off-by: Nad Alaba <37968805+nadalaba@users.noreply.github.com>
PR-URL: nodejs#63117
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Signed-off-by: avivkeller <me@aviv.sh>
PR-URL: nodejs#63493
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Rename WebCrypto operation parameters and local variables to match the
spec terminology.

Use operation, algorithm, and key names consistently between the docs
and implementation.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63518
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Drive the regression test from the WebCrypto algorithm registry so all
supported algorithms and operations must add explicit coverage
regardless of whether they are native-job backed or js-based.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63520
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Refs: nodejs#62761
Signed-off-by: StefanStojanovic <stefan.stojanovic@janeasystems.com>
PR-URL: nodejs#63413
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Signed-off-by: Mohamed Sayed <k@3zrv.com>
PR-URL: nodejs#63529
Fixes: nodejs#63514
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63556
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63556
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63556
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63556
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Signed-off-by: Mert Can Altin <mertgold60@gmail.com>
PR-URL: nodejs#63385
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Fix build warnings by casting the number literals to the size_t
constants they are compared against.

Signed-off-by: Maya Lekova <maya@igalia.com>
PR-URL: nodejs#63490
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
PR-URL: nodejs#63668
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: nodejs#63669
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Signed-off-by: Mohamed Sayed <k@3zrv.com>
PR-URL: nodejs#63601
Fixes: nodejs#63513
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: nodejs#63293
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This function call can fail with `Z_VERSION_ERROR` if the compiled
library vs loaded library mismatched in version number or in
stream structure size.
In those cases, zlib doesn't initialize the `strm_.msg` field to
null. Therefore, when a `CompressionError` object is created via
`ErrorForMessage()`, it can read a stale or uninitialized `strm_.msg`
pointer that will cause a crash.

Example ASAN report:
```
AddressSanitizer: SEGV on unknown address
    #0 __strlen_avx2
        string/../sysdeps/x86_64/multiarch/strlen-avx2.S:76
    nodejs#1 strlen (/work/node/out/Debug/node+0x1a42ab7)
    nodejs#2 v8::(anonymous namespace)::StringLength(char const*)
        /work/node/out/../deps/v8/src/api/api.cc:7581:16
    nodejs#3 v8::(anonymous namespace)::StringLength(unsigned char const*)
        /work/node/out/../deps/v8/src/api/api.cc:7587:10
    nodejs#4 v8::String::NewFromOneByte(v8::Isolate*,
        unsigned char const*, v8::NewStringType, int)
        /work/node/out/../deps/v8/src/api/api.cc:7677:3
    nodejs#5 node::OneByteString(v8::Isolate*,
        char const*, int, v8::NewStringType)
        /work/node/out/../src/util-inl.h:166:10
    nodejs#6 node::(anonymous namespace)::CompressionStream<
        node::(anonymous namespace)::ZlibContext>
        ::EmitError(node::(anonymous namespace)
        ::CompressionError const&)
        /work/node/out/../src/node_zlib.cc:565:7
    nodejs#7 node::(anonymous namespace)::CompressionStream<
        node::(anonymous namespace)::ZlibContext>
        ::CheckError()
        /work/node/out/../src/node_zlib.cc:519:5
    nodejs#8 node::(anonymous namespace)::CompressionStream<
        node::(anonymous namespace)::ZlibContext>
        ::AfterThreadPoolWork(int)
        /work/node/out/../src/node_zlib.cc:543:10
    nodejs#9 node::ThreadPoolWork::ScheduleWork()
        ::'lambda'(uv_work_s*, int)
        ::operator()(uv_work_s*, int) const
        /work/node/out/../src/threadpoolwork-inl.h:57:15
    nodejs#10 node::ThreadPoolWork::ScheduleWork()
        ::'lambda'(uv_work_s*, int)
        ::__invoke(uv_work_s*, int)
        /work/node/out/../src/threadpoolwork-inl.h:48:7
    nodejs#11 uv__work_done /work/libuv-1.51.0/src/threadpool.c:330:5
    nodejs#12 uv__async_io.part.0
        /work/libuv-1.51.0/src/unix/async.c:208:5
```

Signed-off-by: ndossche <nora.dossche@ugent.be>
PR-URL: nodejs#63476
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Signed-off-by: arbinger <alphaleadershipyt@protonmail.com>
PR-URL: nodejs#63050
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
PR-URL: nodejs#63670
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
PR-URL: nodejs#63545
Refs: nodejs#55794
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Signed-off-by: Tobias Nießen <tniessen@tnie.de>
PR-URL: nodejs#63644
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Update the setRawMode documentation to specify that raw mode disables
special processing of input characters only. Output processing, such as
newline translation on Unix terminals, is not affected.

Fixes: nodejs#63059
Signed-off-by: zeeshan56656 <zeeshan130710@gmail.com>
PR-URL: nodejs#63438
Reviewed-By: Anna Henningsen <anna@addaleax.net>
A recursively watched directory can be removed after a parent watcher
observes it but before the non-native recursive watcher scans it.

Ignore ENOENT from the directory scan so this deletion race does not
emit an unhandled watcher error.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: nodejs#63686
Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-06-01.md#jstest-failure
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Use common.nodeProcessAborted() for the intentional abort path so
platform-specific abort signals such as SIGILL are accepted.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: nodejs#63687
Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-06-01.md#jstest-failure
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Signed-off-by: Herrtian <70463940+Herrtian@users.noreply.github.com>
PR-URL: nodejs#63542
Fixes: nodejs#62774
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Signed-off-by: Daijiro Wachi <daijiro.wachi@gmail.com>
PR-URL: nodejs#63700
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Tierney Cyren <hello@bnb.im>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: nodejs#63707
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
mcollina and others added 23 commits July 22, 2026 15:20
The substring check env[key].indexOf(--permission) !== -1 in
copyPermissionModelFlagsToEnv falsely treats unrelated NODE_OPTIONS
values like --title=--permission as if the child already has an
explicit Permission Model policy. This prevents flag propagation,
causing the child to run without process.permission.

Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: nodejs#63972
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Signed-off-by: Chengzhong Wu <cwu631@bloomberg.net>
PR-URL: nodejs#64221
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Bumps the eslint group in /tools/eslint with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `8.0.0-rc.6` | `8.0.1` |
| [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) | `8.0.0-rc.6` | `8.0.1` |
| [@babel/plugin-syntax-import-defer](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-syntax-import-defer) | `8.0.0-rc.6` | `8.0.1` |
| [@babel/plugin-syntax-import-source](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-syntax-import-source) | `8.0.0-rc.6` | `8.0.1` |
| [eslint](https://github.com/eslint/eslint) | `10.4.0` | `10.5.0` |
| [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) | `63.0.0` | `63.0.9` |
| [eslint-plugin-regexp](https://github.com/ota-meshi/eslint-plugin-regexp) | `3.1.0` | `3.1.1` |
| [globals](https://github.com/sindresorhus/globals) | `17.6.0` | `17.7.0` |

Updates `@babel/core` from 8.0.0-rc.6 to 8.0.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.1/packages/babel-core)

Updates `@babel/eslint-parser` from 8.0.0-rc.6 to 8.0.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.1/eslint/babel-eslint-parser)

Updates `@babel/plugin-syntax-import-defer` from 8.0.0-rc.6 to 8.0.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.1/packages/babel-plugin-syntax-import-defer)

Updates `@babel/plugin-syntax-import-source` from 8.0.0-rc.6 to 8.0.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.1/packages/babel-plugin-syntax-import-source)

Updates `eslint` from 10.4.0 to 10.5.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v10.4.0...v10.5.0)

Updates `eslint-plugin-jsdoc` from 63.0.0 to 63.0.9
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](gajus/eslint-plugin-jsdoc@v63.0.0...v63.0.9)

Updates `eslint-plugin-regexp` from 3.1.0 to 3.1.1
- [Release notes](https://github.com/ota-meshi/eslint-plugin-regexp/releases)
- [Changelog](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/CHANGELOG.md)
- [Commits](ota-meshi/eslint-plugin-regexp@v3.1.0...v3.1.1)

Updates `globals` from 17.6.0 to 17.7.0
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](sindresorhus/globals@v17.6.0...v17.7.0)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@babel/eslint-parser"
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@babel/plugin-syntax-import-defer"
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@babel/plugin-syntax-import-source"
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: eslint
  dependency-version: 10.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: eslint-plugin-jsdoc
  dependency-version: 63.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: eslint-plugin-regexp
  dependency-version: 3.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: globals
  dependency-version: 17.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
PR-URL: nodejs#64249
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Consolidate the spec's per-chunk predicate chains (CanCloseOrEnqueue,
IsLocked, HasDefaultReader, GetNumReadRequests, GetDesiredSize and the
writable-side equivalents) into single passes over the controller and
stream state, mirror "close queued or in flight" as a boolean flag
maintained at the few close-request transition sites, and materialize
the TransformStream [[backpressureChangePromise]] record lazily on
first observation so backpressure flips nobody is waiting on allocate
nothing.

Assisted-by: Claude Code
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: nodejs#64252
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Signed-off-by: Guy Bedford <guybedford@gmail.com>
PR-URL: nodejs#63951
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63104
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63134
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63556
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Move KeyObject.prototype.toCryptoKey() onto the base KeyObject
class and dispatch from the cached native key type. Both secret and
asymmetric conversions now pass a KeyObjectHandle through the Web
Crypto import paths.

Expose KeyObjectHandle.prototype.getKeyType() so asymmetric importers
can validate public/private usages without wrapping the handle back
into a KeyObject. Secret importers likewise consume KeyObjectHandle
directly.

Use the shared asymmetric conversion helper to derive public
CryptoKeys for SubtleCrypto.getPublicKey(), avoiding the temporary
PrivateKeyObject/createPublicKey round trip while keeping usage
validation in the import path.

Update getPublicKey and KeyObject.toCryptoKey tests to be driven from
the Web Crypto supported-algorithm registry so new algorithms require
either coverage or an explicit skip.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63622
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: nodejs#63900
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Introduce prepareSubtleMethod() and convertSubtleArgument() for the
common SubtleCrypto call prelude. Methods now reuse the same receiver
check, required-argument check, error prefix construction, argument
context selection, and WebIDL conversion path.

Introduce WebCrypto key usage helpers for common usage validation and
key pair usage splitting. Algorithm modules now define their allowed
public, private, and key generation usages once, then call the shared
helpers from generateKey() and importKey() paths.

This removes repeated function-invocation setup in webcrypto.js and
repeated key usage checks across the WebCrypto algorithm modules while
preserving the existing validation behavior.

Mark normalized-algorithm fallback branches as unreachable assertions.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63975
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Add shared bit-length helpers for WebCrypto operations that accept bit
sequences whose length is not byte-aligned.

Use the helpers for cSHAKE output, ECDH-derived bits, HMAC/KMAC key
generation/import/derivation, and KMAC sign/verify output. Preserve the
requested bit length in CryptoKey algorithm metadata while storing and
exporting rounded-up byte material with unused low bits cleared.

Keep byte-multiple validation for algorithms whose specs require it.

Extend the lower-end of KMAC's key length support.

Enable cSHAKE customization and functionName parameters.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63988
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Return false for Ed25519 and Ed448 one-shot verification when the public
key or signature R component is a known low-order point. This keeps key
import behavior unchanged while making WebCrypto verification match WPT
expectations across OpenSSL variants.

Remove the stale WPT expected-failure entry and add focused regression
coverage for both curves.

Closes: nodejs#54572

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#64026
Backport-PR-URL: nodejs#64629
Fixes: nodejs#54572
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#64033
Backport-PR-URL: nodejs#64629
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Original commit message:

    optimize ascii fast path in WriteUtf8V2

    Change-Id: If28168cb4395b953d0ec642ef4fc618ce963dbcd
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7124103
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Commit-Queue: Erik Corry <erikcorry@chromium.org>
    Reviewed-by: Erik Corry <erikcorry@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#103542}

Refs: v8/v8@64b36b4
PR-URL: nodejs#61712
Backport-PR-URL: nodejs#64630
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Add a samplePerIteration option to monitorEventLoopDelay that records
event loop delay from libuv event loop iterations instead of the timer
interval sampler. The default remains interval-based; existing uses of
monitorEventLoopDelay() keep behaving the same unless the
samplePerIteration option is passed through.

Signed-off-by: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
PR-URL: nodejs#62935
Backport-PR-URL: nodejs#64480
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Signed-off-by: Chengzhong Wu <cwu631@bloomberg.net>
PR-URL: nodejs#63626
Backport-PR-URL: nodejs#64632
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
With the introduction of always static target `node_base`,
`node_aix_shared` is now redundant.

Signed-off-by: Chengzhong Wu <cwu631@bloomberg.net>
PR-URL: nodejs#63747
Backport-PR-URL: nodejs#64632
Refs: nodejs#63626
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Original commit message:

    [api] Add V8::GetWasmMemoryReservationSizeInBytes()

    When the system does not have enough virtual memory for the wasm
    cage, installing the trap handler would cause any code allocating
    wasm memory to throw. Therefore it's useful for the embedder to
    know when the system doesn't have enough virtual address space
    to allocate enough wasm cages and in that case, skip the
    trap handler installation so that wasm code can at least work
    (even not at the maximal performance).

    Node.js previously has a command line option
    --disable-wasm-trap-handler to fully disable trap-based bound checks,
    this new API would allow it to adapt automatically while keeping the
    optimization in the happy path, since it's not always possible for
    end users to opt-into disabling trap-based bound checks (for example,
    when a VS Code Server is loaded in a remote server for debugging).

    Refs: nodejs#62132
    Refs: microsoft/vscode#251777
    Change-Id: I345c076af2b2b47700e5716b49c3133fdf8a0981
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7638233
    Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
    Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Reviewed-by: Clemens Backes <clemensb@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#105702}

Refs: v8/v8@bef0d9c
Co-authored-by: Joyee Cheung <joyeec9h3@gmail.com>
PR-URL: nodejs#62132
Backport-PR-URL: nodejs#64338
Refs: microsoft/vscode#251777
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/7638233
Signed-off-by: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
PR-URL: nodejs#62132
Backport-PR-URL: nodejs#64338
Refs: microsoft/vscode#251777
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/7638233
Signed-off-by: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
PR-URL: nodejs#60798
Backport-PR-URL: nodejs#63659
Signed-off-by: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: nodejs#60798
Backport-PR-URL: nodejs#63659
Signed-off-by: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: nodejs#61610
Backport-PR-URL: nodejs#63659
Signed-off-by: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
@aduh95
aduh95 requested a review from a team as a code owner July 22, 2026 13:20
semimikoh and others added 2 commits July 22, 2026 13:25
Blob.prototype.stream() registered a wakeup callback on the
underlying source's start() and never released it. The strong
Reader::wakeup_ handle kept the reader -- and through it the
blob's DataQueue and backing store -- reachable as a GC root, so
the source buffer leaked on every stream() call. On Node 26+,
streaming a 1 MiB blob 300 times retained ~300 MiB in
process.memoryUsage().arrayBuffers while the V8 heap stayed small.

Register the wakeup lazily in pull() and clear it on every terminal
or idle path (EOS, error, cancel, backpressure), mirroring the
cleanup already done by the async iterator path. The strong handle
now only lives while a pull is in flight, so the reader and its
backing store become collectable once the stream finishes, errors,
is cancelled, or goes idle under backpressure.

Fixes: nodejs#63574

Signed-off-by: semimikoh <ejffjeosms@gmail.com>
PR-URL: nodejs#63577
Fixes: nodejs#63574
Reviewed-By: James M Snell <jasnell@gmail.com>
(cherry picked from commit 243905a)
Backport prerequisite for the previous commit (backport of nodejs#63577).

The Blob.stream() leak fix clears the reader's wakeup handle by calling
reader.setWakeup(undefined) on every terminal/idle path. On main the C++
Blob::Reader::SetWakeup already tolerates an undefined argument
(resetting the strong wakeup_ handle), but that guard is not present on
v24.x -- it landed incidentally in the large QUIC implementation commit
cf91d18 (nodejs#62876), which is not itself being backported.

Extract only the minimal node_blob.cc SetWakeup hunk from that commit so
the JS fix works on v24.x. Without it, setWakeup(undefined) aborts with
`Assertion failed: args[0]->IsFunction()` at src/node_blob.cc. The
NotifyPull(fin)/pull_pending_ coalescing from the same upstream commit
is QUIC-specific, not required by the leak fix, and is intentionally
omitted.

Refs: nodejs#63577
Refs: nodejs#62876
Signed-off-by: Gabe Bryk <gbryk11@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. v24.x Issues that can be reproduced on v24.x or PRs targeting the v24.x-staging branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.